package com.dms.modules.payment.controller;

import com.dms.common.api.ApiResponse;
import com.dms.modules.payment.entity.AlipayOrder;
import com.dms.modules.payment.service.AlipayService;
import com.dms.modules.order.entity.Order;
import com.dms.modules.order.service.OrderService;
import com.dms.modules.message.service.BusinessMessageService;
import com.dms.modules.message.dto.BusinessMessageDTO;
import com.dms.modules.message.enums.BusinessMessageType;
import com.dms.modules.order.enums.OrderStatus;
import com.dms.modules.cart.service.CartService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/api/v1/payment/alipay")
@Api(tags = "支付宝支付回调接口")
@RequiredArgsConstructor
public class AlipayController {

    private final AlipayService alipayService;
    private final OrderService orderService;
    private final BusinessMessageService businessMessageService;
    private final CartService cartService;

    @PostMapping("/notify")
    @ApiOperation("支付宝异步通知")
    @PreAuthorize("permitAll()")  // 允许所有访问
    public String handleNotify(HttpServletRequest request) {
        try {
            // 记录原始请求信息
            log.info("收到支付宝回调请求: ContentType={}, Method={}", 
                    request.getContentType(), request.getMethod());

            // 1. 获取所有请求参数
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            
            // 记录原始参数Map
            log.info("原始请求参数: {}", requestParams);
            
            for (String name : requestParams.keySet()) {
                String[] values = requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i]
                            : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }
            
            log.info("收到支付宝异步通知: params={}", params);

            // 2. 获取订单信息
            String orderNo = params.get("out_trade_no");
            
            // 处理合并支付的情况
            if (orderNo.contains("_m")) {
                // 移除合并支付的后缀，获取原始订单号
                String baseOrderNo = orderNo.substring(0, orderNo.indexOf("_m"));
                
                // 查询关联的所有订单
                List<Order> orders = orderService.lambdaQuery()
                    .like(Order::getOrderNo, baseOrderNo + "%")
                    .eq(Order::getStatus, OrderStatus.PENDING_PAYMENT.getCode())
                    .list();
                
                if (orders.isEmpty()) {
                    log.error("未找到相关订单: orderNo={}", orderNo);
                    return "failure";
                }

                // 3. 调用Service处理回调
                boolean result = alipayService.handleNotify(params);
                
                if (result) {
                    // 4. 处理所有关联订单
                    for (Order order : orders) {
                        try {
                            // 更新订单状态
                            order.setStatus(OrderStatus.PENDING_SHIPMENT.getCode());
                            order.setPaymentMethod("alipay");
                            order.setPaymentNo(params.get("trade_no"));
                            order.setPaymentTime(LocalDateTime.now());
                            order.setUpdateTime(LocalDateTime.now());
                            orderService.updateById(order);

                            // 清理购物车
                            if (order.getCartItemIds() != null && !order.getCartItemIds().isEmpty()) {
                                String[] cartItemIdArray = order.getCartItemIds().split(",");
                                List<Long> cartItemIds = Arrays.stream(cartItemIdArray)
                                    .map(Long::parseLong)
                                    .collect(Collectors.toList());
                                
                                cartService.removeByIds(cartItemIds);
                                log.info("清理购物车成功: orderId={}, cartItemIds={}", order.getId(), cartItemIds);
                            }

                            // 发送商家通知
                            try {
                                BusinessMessageDTO messageDTO = BusinessMessageDTO.builder()
                                    .type(BusinessMessageType.ORDER_PAID)
                                    .businessId(order.getId())
                                    .userId(order.getMerchantId())
                                    .params(buildMessageParams(order))
                                    .build();
                                
                                businessMessageService.sendBusinessMessage(messageDTO);
                            } catch (Exception e) {
                                log.error("发送商家通知失败: orderId={}, merchantId={}, error={}", 
                                    order.getId(), order.getMerchantId(), e.getMessage(), e);
                            }
                        } catch (Exception e) {
                            log.error("处理订单失败: orderId={}, error={}", order.getId(), e.getMessage(), e);
                            return "failure";
                        }
                    }
                }
                
                // 5. 返回结果
                String response = result ? "success" : "failure";
                log.info("处理支付宝回调完成，响应: {}", response);
                return response;
            } else {
                // 处理单个订单的情况
                Order order = orderService.lambdaQuery()
                    .eq(Order::getOrderNo, orderNo)
                    .one();
                    
                if (order == null) {
                    log.error("订单不存在: orderNo={}", orderNo);
                    return "failure";
                }

                // 3. 调用Service处理回调
                boolean result = alipayService.handleNotify(params);
                
                if (result) {
                    // 4. 更新订单状态
                    order.setStatus(OrderStatus.PENDING_SHIPMENT.getCode());
                    order.setPaymentMethod("alipay");
                    order.setPaymentNo(params.get("trade_no"));
                    order.setPaymentTime(LocalDateTime.now());
                    order.setUpdateTime(LocalDateTime.now());
                    orderService.updateById(order);

                    // 清理购物车
                    if (order.getCartItemIds() != null && !order.getCartItemIds().isEmpty()) {
                        String[] cartItemIdArray = order.getCartItemIds().split(",");
                        List<Long> cartItemIds = Arrays.stream(cartItemIdArray)
                            .map(Long::parseLong)
                            .collect(Collectors.toList());
                        
                        cartService.removeByIds(cartItemIds);
                        log.info("清理购物车成功: orderId={}, cartItemIds={}", order.getId(), cartItemIds);
                    }

                    // 发送商家通知
                    try {
                        BusinessMessageDTO messageDTO = BusinessMessageDTO.builder()
                            .type(BusinessMessageType.ORDER_PAID)
                            .businessId(order.getId())
                            .userId(order.getMerchantId())
                            .params(buildMessageParams(order))
                            .build();
                        
                        businessMessageService.sendBusinessMessage(messageDTO);
                    } catch (Exception e) {
                        log.error("发送商家通知失败: orderId={}, merchantId={}, error={}", 
                            order.getId(), order.getMerchantId(), e.getMessage(), e);
                    }
                }
                
                // 5. 返回结果
            String response = result ? "success" : "failure";
            log.info("处理支付宝回调完成，响应: {}", response);
            return response;
            }
        } catch (Exception e) {
            log.error("处理支付宝回调异常", e);
            return "failure";
        }
    }

    // @GetMapping("/return")
    // @ApiOperation("支付宝同步返回")
    // @PreAuthorize("permitAll()")  // 允许所有访问
    // public void handleReturn(HttpServletRequest request, HttpServletResponse response) {
    //     try {
    //         Map<String, String> params = request.getParameterMap().entrySet().stream()
    //             .collect(java.util.stream.Collectors.toMap(
    //                 Map.Entry::getKey,
    //                 e -> e.getValue()[0]
    //             ));
            
    //         log.info("收到支付宝同步返回: {}", params);
            
    //         // 获取订单号和支付状态
    //         String orderNo = params.get("out_trade_no");
    //         String tradeStatus = params.get("trade_status");
            
    //         // 构建前端支付结果页面URL
    //         String frontendUrl = "http://localhost:8081/pages/order/pay/result";  // 替换为实际的前端URL
    //         String redirectUrl = String.format("%s?orderNo=%s&status=%s", 
    //             frontendUrl, 
    //             orderNo,
    //             "TRADE_SUCCESS".equals(tradeStatus) ? "success" : "fail"
    //         );
            
    //         // 重定向到前端页面
    //         response.sendRedirect(redirectUrl);
    //     } catch (Exception e) {
    //         log.error("处理支付宝同步返回失败", e);
    //         try {
    //             // 发生错误时重定向到错误页面
    //             response.sendRedirect("http://localhost:8081/pages/order/pay/error");  // 替换为实际的前端错误页面URL
    //         } catch (IOException ex) {
    //             log.error("重定向到错误页面失败", ex);
    //         }
    //     }
    // }
    @GetMapping("/return")
    @ApiOperation("支付宝同步返回")
    @PreAuthorize("permitAll()")  // 允许所有访问
    public void handleReturn(HttpServletRequest request, HttpServletResponse response) {
        try {
            Map<String, String> params = request.getParameterMap().entrySet().stream()
                .collect(java.util.stream.Collectors.toMap(
                    Map.Entry::getKey,
                    e -> e.getValue()[0]
                ));
            
            log.info("收到支付宝同步返回: {}", params);
            
            // 获取订单号
            String orderNo = params.get("out_trade_no");
            
            // 支付宝同步返回时，说明支付一定成功了
            String status = "success";
            
            // 构建前端支付结果页面URL（注意添加 /#/ 前缀）
            String frontendUrl = "http://localhost:8081/#/pages/order/pay/result";  // 替换为实际的前端URL
            
            // 使用 out_trade_no 参数，这样前端可以正确识别是支付宝返回
            String redirectUrl = String.format("%s?out_trade_no=%s", 
                frontendUrl, 
                orderNo
            );
            
            log.info("重定向到前端页面: {}", redirectUrl);
            
            // 重定向到前端页面
            response.sendRedirect(redirectUrl);
        } catch (Exception e) {
            log.error("处理支付宝同步返回失败", e);
            try {
                // 发生错误时重定向到错误页面（注意添加 /#/ 前缀）
                response.sendRedirect("http://localhost:8081/#/pages/order/pay/error");  // 替换为实际的前端错误页面URL
            } catch (IOException ex) {
                log.error("重定向到错误页面失败", ex);
            }
        }
    }
    @GetMapping("/query/{orderNo}")
    @ApiOperation("查询订单状态")
    public ApiResponse<AlipayOrder> queryOrder(@PathVariable String orderNo) {
        AlipayOrder order = alipayService.queryOrder(orderNo);
        return ApiResponse.success(order);
    }

    /**
     * 构建消息参数
     */
    private Map<String, Object> buildMessageParams(Order order) {
        Map<String, Object> params = new HashMap<>();
        params.put("orderNo", order.getOrderNo());
        params.put("totalAmount", order.getTotalAmount().toString());
        params.put("payAmount", order.getPayAmount().toString());
        return params;
    }
} 